<template>
	<div ref="refDivDom" class="number-digital" :style="domStyle">
		<div class="box-item">
			<li
				:key="index"
				v-for="(item, index) in orderNum"
				:class="{ 'number-item': !isNaN(item), 'mark-item': isNaN(item) }"
				:style="{ marginRight: needDivideMgright(index) }"
			>
				<span v-if="!isNaN(item)">
					<i :id="`numberItem${index}`">0123456789</i>
				</span>
				<div v-if="needDivideDot(index)" class="num-dot">,</div>
			</li>
		</div>
	</div>
</template>

<script lang="ts" setup name="NumberAnimation">
const props = defineProps<{
	numm: number | string;
	numLen: number;
	noneDivide?: boolean; // 默认需要超过7位数字以上以,分隔
}>();

const refDivDom = ref();

const needDivideDot = (index: number): boolean => {
	if (props.noneDivide) {
		// 不需要分隔符
		return false;
	}
	if (props.numLen <= 7) {
		return false;
	}
	return index === props.numLen - 8 || index === props.numLen - 5;
};
const needDivideMgright = (index: number): string => {
	if (props.noneDivide) {
		// 不需要分隔符
		return '2px';
	}
	if (props.numLen <= 7) {
		return '2px';
	}
	return index === props.numLen - 7 || index === props.numLen - 4 ? '14px' : '2px';
};

const orderNum = ref<Array<number>>([]);
// 处理数字
// numm: 传入的数字  numLen: 默认显示几位数
const toOrderNum = (num: string | number): void => {
	num = num.toString();
	if (num.length < props.numLen) {
		num = '0' + num; // 如未满定义的位数，添加"0"补位
		toOrderNum(num); // 递归添加"0"补位
	} else if (num.length === props.numLen) {
		orderNum.value = num.split('') as unknown as number[]; // 将其便变成数据，渲染至滚动数组
	}
};

const setNumberTransform = (): void => {
	for (let index = 0; index < orderNum.value.length; index++) {
		const ele: HTMLDivElement = document.getElementById(`numberItem${index}`) as HTMLDivElement;
		if (ele) {
			ele.style.transform = `translate(-50%, -${(orderNum.value[index] as number) * 10}%)`;
		}
	}
};
const watchStop = watch(
	() => props.numm,
	() => {
		toOrderNum(props.numm);
		setTimeout(() => {
			setNumberTransform();
		}, 200);
	}
);

const domStyle = reactive({
	marginLeft: '0px'
});
const setDomStyle = (): void => {
	let observer = new ResizeObserver((entries) => {
		const halfWidth = (entries[0].target as HTMLDivElement).offsetWidth / 2;
		domStyle['marginLeft'] = `-${halfWidth}px`;
	});

	nextTick(() => {
		// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
		observer.observe(refDivDom.value!);
	});
};

toOrderNum(props.numm);

onMounted(() => {
	setTimeout(() => {
		setNumberTransform();
	}, 200);

	setDomStyle();
});
onUnmounted(() => {
	watchStop();
});
</script>

<style lang="less" scoped>
.number-digital {
	position: absolute;
	top: 180px;
	left: 50%;
	cursor: pointer;

	.box-item {
		position: relative;
		display: flex;
		list-style: none;
		font-size: 32px;
		line-height: 32px;
		text-align: center;
		color: #2d7cff;
	}

	/* 滚动数字设置 */
	.number-item {
		list-style: none;
		width: 20px;
		height: 42px;
		margin-right: 0 !important;
		font-family: 'D-DIN';
		font-size: 32px;
		font-weight: 700;
		color: #fff;

		& > span {
			position: relative;
			display: inline-block;
			overflow: hidden;
			width: 100%;
			height: 100%;
			margin-right: 10px;
			writing-mode: vertical-rl;
			text-orientation: upright;

			& > i {
				position: absolute;
				top: 8px;
				left: 50%;
				font-family: 'D-DIN';
				font-size: 32px;
				font-weight: 700;
				font-style: normal;
				letter-spacing: 10px;
				transition: transform 1s ease-in-out;
				transform: translate(-50%, 0);
			}
		}
	}

	.number-item:last-child {
		margin-right: 0;
	}

	.num-dot {
		display: inline-block;
		height: 53px;
		margin-left: 8px;
		font-family: MiSans, MiSans-Demibold;
		font-size: 47px;
		font-weight: 400;
		line-height: 47px;
		text-align: center;
		color: #fff;
	}
}
</style>
